
#include "xtypes.h"
#include "xaux.h"
#include "util_image.h"
#include <stdlib.h>

void raster_circle(CxSphereCanvas* pCanvas, int_t x0, int_t y0, int_t radius, DWORD cr)
{
	int_t f = 1 - radius;
	int_t ddF_x = 0;
	int_t ddF_y = -2 * radius;
	int_t x = 0;
	int_t y = radius;

	pCanvas->SetPixel(x0, y0 + radius, cr);
	pCanvas->SetPixel(x0, y0 - radius, cr);
	pCanvas->SetPixel(x0 + radius, y0, cr);
	pCanvas->SetPixel(x0 - radius, y0, cr);

	while(x < y)
	{
		if(f >= 0)
		{
			y--;
			ddF_y += 2;
			f += ddF_y;
		}
		x++;
		ddF_x += 2;
		f += ddF_x + 1;
		pCanvas->SetPixel(x0 + x, y0 + y, cr);
		pCanvas->SetPixel(x0 - x, y0 + y, cr);
		pCanvas->SetPixel(x0 + x, y0 - y, cr);
		pCanvas->SetPixel(x0 - x, y0 - y, cr);
		pCanvas->SetPixel(x0 + y, y0 + x, cr);
		pCanvas->SetPixel(x0 - y, y0 + x, cr);
		pCanvas->SetPixel(x0 + y, y0 - x, cr);
		pCanvas->SetPixel(x0 - y, y0 - x, cr);
	}
}



void bresenham_line(CxSphereCanvas* pCanvas, int_t x0,int_t y0,int_t x1,int_t y1, DWORD cr)
{
	if(pCanvas==NULL){ return; }

	bool_t steep = AUX_ABS(y1 - y0) > AUX_ABS(x1 - x0);
	if(steep) {
		xSwapVar(x0, y0);
		xSwapVar(x1, y1);
	}

	if(x0>x1) {
		xSwapVar(x0, x1);
		xSwapVar(y0, y1);
	}

	int_t deltax = x1-x0;
	int_t deltay = AUX_ABS(y1-y0);
	int_t error = - (deltax>>1);
	int_t ystep;
	int_t x;
	int_t y = y0;
	if(y0<y1)
		ystep = 1;
	else
		ystep = -1;

	for(x=x0;x<=x1;++x)
	{
		if(steep)
			pCanvas->SetPixel(y,x,cr);
		else
			pCanvas->SetPixel(x,y,cr);

		error += deltay;
		if(error>0)
		{
			y += ystep;
			error -= deltax;
		}

	}

	return;
}


void dda_line(CxSphereCanvas& canvas, int xa,int ya,int xb,int yb, DWORD cr)
{
	float delta_x,delta_y,x,y;
	int dx,dy,steps,k;
	dx=xb-xa;
	dy=yb-ya;
	if(abs(dx)>abs(dy))
		steps=abs(dx);
	else
		steps=abs(dy);
	delta_x=(float)dx/(float)steps;
	delta_y=(float)dy/(float)steps;
	x=xa;
	y=ya;
	canvas.SetPixel(x,y,cr);
	for(k=1;k<=steps;k++)
	{
		x+=delta_x;
		y+=delta_y;
		canvas.SetPixel(x,y,cr);
	}
	return;
}



void dda_line_ip(CxSphereCanvas& canvas, int xa,int ya,int xb,int yb, DWORD crs, DWORD cre)
{
	float delta_x,delta_y,x,y;
	int dx,dy,steps,k;
	dx=xb-xa;
	dy=yb-ya;

	if(abs(dx)>abs(dy))
		steps=abs(dx);
	else
		steps=abs(dy);

	delta_x=(float)dx/(float)steps;
	delta_y=(float)dy/(float)steps;
	x=xa;
	y=ya;
	canvas.SetPixel(x,y,crs);

	int_t cs1,cs2,cs3,cs4, ce1,ce2,ce3,ce4, c1,c2,c3,c4;

	cs1 = ((BYTE)(crs));
	cs2 = ((BYTE)(((WORD)(crs)) >> 8));
	cs3 = ((BYTE)((crs)>>16));
	cs4 = ((BYTE)((crs)>>24));

	ce1 = ((BYTE)(cre));
	ce2 = ((BYTE)(((WORD)(cre)) >> 8));
	ce3 = ((BYTE)((cre)>>16));
	ce4 = ((BYTE)((cre)>>24));

	float f;

	for(k=1;k<=steps;k++)
	{
		x+=delta_x;
		y+=delta_y;

		f = ((float)k)/steps;
		c1 = cs1*(1-f) + ce1*f;
		c2 = cs2*(1-f) + ce2*f;
		c3 = cs3*(1-f) + ce3*f;
		c4 = cs4*(1-f) + ce4*f;

		c1 = AUX_FIX_SUBRANGE_VALID(c1,0,255);
		c2 = AUX_FIX_SUBRANGE_VALID(c2,0,255);
		c3 = AUX_FIX_SUBRANGE_VALID(c3,0,255);
		c4 = AUX_FIX_SUBRANGE_VALID(c4,0,255);

		canvas.SetPixel(x,y,AUX_MAKEDWORD(c1,c2,c3,c4));
	}
	return;
}
